/*=====================================================================
  This file is part of a Microsoft SQL Server Shared Source Application.
  Copyright (C) Microsoft Corporation.  All rights reserved.
 
THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
======================================================= */

using System;
using System.IO;
using System.Collections;
using System.Xml;

namespace Microsoft.SqlServer.BI.ASLoadSim
{
    public enum CustomDataAccessMethod
    {
        Random = 0,
        Sequential = 1
    }

	public class CustomDataSource
	{
        private string m_fileName;
        public string FileName
        {
            get
            {
                return m_fileName;
            }
        }

        private CustomDataAccessMethod m_accessMethod;
        public CustomDataAccessMethod AccessMethod
        {
            get
            {
                return m_accessMethod;
            }
        }

        private ArrayList m_queries;

        public CustomDataSource(string fileName, string accessMethod)
        {
            m_fileName = fileName;

            try
            {
                switch (accessMethod.ToLower())
                {
                    case "random":
                        m_accessMethod = CustomDataAccessMethod.Random;
                        break;
                    case "sequential":
                        m_accessMethod = CustomDataAccessMethod.Sequential;
                        break;
                    default:
                        // error handling
                        throw new Exception("Access Mode has to be either \"Random\" or \"Sequential\". " +
                                            "The one you specify - \"" + 
                                            accessMethod +
                                            " \" is not valid.");
                }

                m_queries = new ArrayList();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// Read in all queries in the client file.
        /// </summary>
        /// <param name="clientFileName"></param>
        public void Initialize()
        {
            try
            {
                StreamReader sr = new StreamReader(m_fileName);

                XmlReader reader = XmlReader.Create(sr);

                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            break;
                        case XmlNodeType.Text:
                            m_queries.Add(reader.Value);
                            break;
                        case XmlNodeType.EndElement:
                            break;
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        // Are there any queries in the collection that haven't been selected? 
        /// </summary>
        /// <returns></returns>
        public bool HasAvaiableQueries()
        {
            if (m_queries.Count == 0)
                return false;
            else
                return true;
        }

        /// <summary>
        /// Get the next available (not executed) query
        /// </summary>
        /// <param name="accessMethod"></param>
        /// <returns></returns>
        public string RetrieveQuery()
        {
            string query = null;

            switch (m_accessMethod)
            {
                case CustomDataAccessMethod.Random :
                    // Find the next available (not used) query.
                    int count = m_queries.Count;
                    Random rand = new Random();
                    int i = rand.Next(0, count);
                    
                    // Return the query
                    query = (string)m_queries[i];
                    m_queries.RemoveAt(i);
                    
                    break;
                case CustomDataAccessMethod.Sequential :
                    // Return the query
                    query = (string)m_queries[0];
                    m_queries.RemoveAt(0);                    

                    break;
            }

            return query;
        }
	}
}